from UI.ui_client import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeWidgetItem, QMessageBox, QSystemTrayIcon, QMenu, QAction
from PyQt5.QtCore import pyqtSignal, QSettings, Qt, QTimer
from PyQt5.QtNetwork import QLocalSocket, QLocalServer
from PyQt5.QtGui import QIcon, QIntValidator
from datetime import datetime
import time
import socket
import threading
from config import *
from images.aaa_rcc import *
from base_protobuff.base_proto_pb2 import *


class Client(QMainWindow, Ui_MainWindow):
    update_message = pyqtSignal(str)  # 用于更新UI的自定义信号
    show_dialog = pyqtSignal(str)
    exit_dialog = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # -----------------新增固定窗口代码------------------ #
        self.setFixedSize(self.size())  # 固定为当前UI设计的大小
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint)
        # -----------------创建一个唯一的命名管道名称------------------ #
        self.pipe_name = 'qy_pipe_python'  # 简化名称
        self.pipe_socket = QLocalSocket()
        self.pipe_server = QLocalServer()
        self.init_pipe()
        # -----------------socket------------------ #
        self.client_socket = None
        self.is_connected = False
        self.receive_thread = None
        # -----------------用户数据------------------ #
        self.name = ""
        self.set_id = 0
        self.ip = None
        self.page_index = 0         # 切页
        self.last_send_time = 0     # 上次发包时间

        # -----------------区服数据------------------ #
        self.c_run_state = 0
        self.c_cur_name = ""
        self.c_task_name = ""
        self.c_lock_name = ""

        # -----------------UI处理------------------ #
        self.setWindowIcon(QIcon(":client/images/main.ico"))
        self.pushButton_lock.setIcon(QIcon(":client/images/lock_a.jpg"))
        self.pushButton_lock.text = "锁定"
        # 初始化QSettings,用于缓存用户记录
        self.settings = QSettings("MyOrganization", "MyApp")

        # -----------------控件事件------------------ #
        # 点击进入按钮
        self.pushButton_enter.clicked.connect(self.clicked_enter)
        # 服务器列表连接双击事件
        self.treeWidget.itemDoubleClicked.connect(self.on_server_selected)

        # -----------------服务器功能界面------------------ #
        self.pushButton_lock.clicked.connect(self.send_lock)
        self.pushButton_auto_make.clicked.connect(self.send_automake)
        self.pushButton_kill_cfg.clicked.connect(self.send_kill_cfg)
        self.pushButton_reload.clicked.connect(self.send_reload)
        self.pushButton_stop.clicked.connect(self.send_stop)
        self.pushButton_del_svr.clicked.connect(self.send_del_svr)
        self.pushButton_syn.clicked.connect(self.send_syn)
        self.pushButton_ask.clicked.connect(self.send_ask)
        self.pushButton_svninfo.clicked.connect(self.send_svninfo)
        self.pushButton_return.clicked.connect(self.change_page_list)

        # -----------------特殊功能界面------------------ #
        self.pushButton_dump.clicked.connect(self.send_dump)
        self.pushButton_set_svr_time.clicked.connect(self.send_set_svr_time)
        self.pushButton_change_page2.clicked.connect(self.change_page_func)
        self.pushButton_return_2.clicked.connect(self.change_page_list)

        # -----------------信号槽------------------ #
        # 连接信号槽
        self.update_message.connect(self.handle_server_response)
        self.show_dialog.connect(self.show_info_dialog)
        self.exit_dialog.connect(self.exit_info_dialog)

        # -----------------启动时做的事情------------------ #
        self._load_settings()

        # 新增定时器
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.on_timer_timeout)
        self.timer_interval = 1000 # 毫秒
        self.timer.start(self.timer_interval)

        # -----------------托盘------------------ #
        self.tray_icon = QSystemTrayIcon(self)
        self.init_tray_icon()

        # 创建一个整数验证器
        int_validator = QIntValidator()
        self.lineEdit_txt_1.setValidator(int_validator)
        self.lineEdit_txt_2.setValidator(int_validator)
        self.lineEdit_txt_3.setValidator(int_validator)
        self.lineEdit_txt_4.setValidator(int_validator)

    """----------------------界面处理函数------------------"""
    # 心跳函数
    def on_timer_timeout(self):
        current_time = int(time.time())
        # print(f"触发定时器： {current_time} page_index： {self.page_index} ")
        if self.page_index != 0:
            if self.is_connected:
                if current_time % 60 == 0:
                    self.send_check_svr()
                    self.send_get_svr_data()
            else:
                if current_time % 30 == 0:
                    self.update_message.emit("正在尝试重新连接服务器……")
                    self.connect_server()
                    if self.is_connected:
                        # self.update_message.emit(f"网络连接成功,正在获取服务器数据……")
                        self.send_login()
                        self.send_check_svr()
                        self.send_get_svr_data()
        else:
            pass

    def init_pipe(self):
        self.pipe_socket.connected.connect(self.pipe_connected)
        self.pipe_socket.error.connect(self.pipe_error)
        self.pipe_socket.connectToServer(self.pipe_name)

        # 如果连接失败，则创建新服务
        if self.pipe_socket.state() != QLocalSocket.ConnectedState:
            if not self.pipe_server.listen(self.pipe_name):
                QMessageBox.critical(self, "错误", "无法启动单实例应用")
                sys.exit(1)
            self.pipe_server.newConnection.connect(self.handle_new_connection)

    def pipe_connected(self):
        # 连接成功，退出当前实例
        self.pipe_socket.disconnectFromServer()
        sys.exit(0)

    def handle_new_connection(self):
        # 有新连接时激活窗口
        tmp_socket = self.pipe_server.nextPendingConnection()
        self.showNormal()
        self.activateWindow()
        self.raise_()
        tmp_socket.disconnectFromServer()

    def pipe_error(self, error):
        if error != QLocalSocket.ConnectionRefusedError:
            print(f"连接命名管道时发生错误：{error}")
            # sys.exit()

    # -----------------托盘功能------------------ #
    def init_tray_icon(self):
        self.tray_icon.setIcon(QIcon(":client/images/main.ico"))

        # 创建托盘菜单
        tray_menu = QMenu()
        show_action = QAction("显示", self)
        exit_action = QAction("退出", self)

        show_action.triggered.connect(self.show_normal)
        exit_action.triggered.connect(self.real_exit)

        tray_menu.addAction(show_action)
        tray_menu.addAction(exit_action)

        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.activated.connect(self.on_tray_activated)
        self.tray_icon.show()

    def show_normal(self):
        """从托盘恢复显示"""
        self.showNormal()
        self.activateWindow()

    def on_tray_activated(self, reason):
        """托盘图标点击事件处理"""
        if reason == QSystemTrayIcon.DoubleClick:
            self.show_normal()

    def real_exit(self):
        # 退出前保存一下设置
        self._save_settings()
        try:
            # 1. 断开网络连接
            self.handle_connection_lost()

            # 2. 等待接收线程结束
            if self.receive_thread and self.receive_thread.is_alive():
                self.receive_thread.join(1.0)  # 适当缩短等待时间

            # 3. 释放Qt相关资源
            if hasattr(self, 'server'):
                self.pipe_server.close()
                self.pipe_server.deleteLater()
            if self.pipe_socket.state() == QLocalSocket.ConnectedState:
                self.pipe_socket.disconnectFromServer()

            # 4. 释放系统托盘资源
            self.tray_icon.hide()
            self.tray_icon.deleteLater()

            # 5. 强制终止应用
            QApplication.processEvents()  # 处理剩余事件
            qApp.quit()
        except Exception as e:
            print(f"Exit error: {str(e)}")
            os._exit(1)  # 紧急退出

    def closeEvent(self, event):
        if self.isVisible():
            event.ignore()
            self.hide()
            self.tray_icon.showMessage(
                "服务器工具",
                "程序已最小化到托盘",
                QSystemTrayIcon.Information,
                2000
            )
        else:
            super().closeEvent(event)

    """加载保存的用户设置"""
    def _save_settings(self):
        self.settings.setValue("UserName", self.lineEdit_name.text())
        self.settings.setValue("ConnectionType", self.comboBox.currentText())

    def _load_settings(self):
        # 加载用户名
        last_username = self.settings.value("UserName", "", type=str)
        self.lineEdit_name.setText(last_username)
        # 加载连接类型
        last_connection = self.settings.value("ConnectionType", "内网连接", type=str)
        index = self.comboBox.findText(last_connection)
        if index >= 0:
            self.comboBox.setCurrentIndex(index)
        else:
            self.comboBox.setCurrentIndex(0)  # 默认选择第一个

    """改变切页"""
    def change_page(self, index):
        self.page_index = index
        self.textBrowser.clear()
        self.stackedWidget.setCurrentIndex(index)
        if index == PAGE_ENTER:
            self.handle_connection_lost()
        elif index == PAGE_SERVER_LIST:
            self.send_change_set_id()

    def _setup_servers(self):
        self.treeWidget.clear()
        root = self.treeWidget.invisibleRootItem()

        # 按组生成树节点
        for group_name in server_list:
            parent = QTreeWidgetItem(root)
            parent.setText(0, group_name)
            for server_id in server_list[group_name]:
                child = QTreeWidgetItem(parent)
                child.setText(0, str(server_id))

        # 展开第一个节点
        if root.childCount() > 0:
            root.child(0).setExpanded(True)

    def clicked_enter(self):
        if self.lineEdit_name.text() is None or self.lineEdit_name.text() == "":
            self.show_dialog.emit("请输入用户名")
            return
        if self.comboBox.currentText() is None or self.comboBox.currentText() == "":
            self.show_dialog.emit("请选择服务器连接")
            return
        self.name = self.lineEdit_name.text()
        self.label_name.setText(self.name)
        if self.comboBox.currentText() == "内网连接":
            self.ip = N_WAN_IP
        elif self.comboBox.currentText() == "外网连接":
            self.ip = W_WAN_IP
        else:
            self.ip = N_WAN_IP
        self.connect_server()
        if self.is_connected is False:
            self.show_dialog.emit("网络连接失败！")
            return
        else:
            self.send_enter()

    def on_server_selected(self, item):
        if self.is_connected is False:
            self.show_dialog.emit("网络连接失败！")
            self.change_page_enter()
        elif item.parent():  # 确保选择的是子节点
            game_set_id = item.text(0)
            print(f"已选择服务器: {game_set_id}")
            self.set_id = int(game_set_id)
            self.label_set.setText(str(self.set_id))
            group_name = "主干服"
            for group, server_ids in server_list.items():
                if self.set_id in server_ids:
                    group_name = group
                    break
            self.label_svr_type.setText(group_name)
            self.change_page_main()
            self.send_login()
            self.send_check_svr()
            self.send_get_svr_data()
        else:
            return

    """消息框处理"""
    def handle_server_response(self, message):
        # 获取当前时间并格式化
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        formatted_msg = f"[{timestamp}] {message}"
        self.textBrowser.append(formatted_msg)

    """弹框功能"""
    def show_info_dialog(self, msg):
        self.showNormal()  # 从托盘恢复
        self.activateWindow()  # 激活窗口
        self.raise_()  # 置顶窗口
        QApplication.processEvents()  # 立即处理UI事件
        msg_box = QMessageBox(
            QMessageBox.Information,
            "服务器工具",
            msg,
            QMessageBox.Ok,
            self  # 关键修改！将父窗口设为MainWindow
        )
        msg_box.setWindowFlags(Qt.Dialog | Qt.WindowStaysOnTopHint)
        msg_box.setWindowModality(Qt.ApplicationModal)
        msg_box.activateWindow()
        msg_box.raise_()
        # 6. 显示对话框
        msg_box.exec_()

    def exit_info_dialog(self, msg):
        self.showNormal()  # 从托盘恢复
        self.activateWindow()  # 激活窗口
        self.raise_()  # 置顶窗口
        QApplication.processEvents()  # 立即处理UI事件
        msg_box = QMessageBox(
            QMessageBox.Critical,
            "服务器工具",
            msg,
            QMessageBox.Ok,
            self  # 关键修改！将父窗口设为MainWindow
        )
        msg_box.setWindowFlags(Qt.Dialog | Qt.WindowStaysOnTopHint)
        msg_box.setWindowModality(Qt.ApplicationModal)
        msg_box.activateWindow()
        msg_box.raise_()
        # 6. 显示对话框
        msg_box.exec_()
        # 退出程序s
        self.real_exit()

    """连接断开处理"""
    def handle_connection_lost(self):
        """连接断开时的清理"""
        if self.client_socket:
            self.client_socket.close()
        # -----------------socket------------------ #
        self.client_socket = None
        self.is_connected = False
        self.receive_thread = None
        # -----------------用户数据------------------ #
        self.name = ""
        self.set_id = 0
        self.ip = None
        # -----------------区服数据------------------ #
        self.c_run_state = 0
        self.c_cur_name = ""
        self.c_task_name = ""
        self.c_lock_name = ""
        self.last_send_time = 0

    def start_progress_bar(self):
        self.progressBar.setMaximum(0)

    def stop_progress_bar(self):
        self.progressBar.setMaximum(1)

    """----------------------基础socket函数------------------"""
    # 发送消息
    def send_message(self, cmd, proto_obj):
        """通用消息发送方法"""
        try:
            body = proto_obj.SerializeToString()
            cmd_byte = cmd.to_bytes(CMD_LEN, byteorder=byteorder_big)
            header = len(body).to_bytes(BODY_LEN, byteorder=byteorder_big)
            self.client_socket.sendall(cmd_byte + header + body)
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")  # 统一使用update_message信号

    # 接收循环
    def receive_loop(self):
        """改良后的接收循环"""
        while self.is_connected:
            try:
                # 阶段1：读取消息头
                header = self.reliable_recv(HEADER_LEN)
                if header is None:
                    continue  # 继续等待数据

                # 解析CMD和长度
                cmd = int.from_bytes(header[:CMD_LEN], byteorder_big)
                body_length = int.from_bytes(header[CMD_LEN:], byteorder_big)

                # 阶段2：读取消息体
                body = self.reliable_recv(body_length)
                if body is None:
                    continue  # 继续等待数据

                # 阶段3：处理协议数据
                if cmd == CMD_RSP:
                    self._handle_response(body)
                elif cmd == CMD_NTF:
                    self._handle_notification(body)
                elif cmd == CMD_SVN_INFO_NTF:
                    self._handle_svn_info_notification(body)
                elif cmd == CMD_SERVER_LIST_NTF:
                    self._handle_server_list_notification(body)
                else:
                    self.update_message.emit(f"未知协议类型: {cmd}")
            except ConnectionResetError:
                self.connection_lost.emit()
                break
            except Exception as e:
                print(f"接收错误 1: {str(e)}")
                self.update_message.emit("网络连接中断 1！")
                continue  # 关键改进：出现异常不退出循环

    # 接收数据
    def reliable_recv(self, length):
        """增强型数据接收方法"""
        data = b''
        try_count = 0
        while self.is_connected and len(data) < length:
            try:
                chunk = self.client_socket.recv(length - len(data))
                if not chunk:
                    if try_count > 3:  # 空数据重试机制
                        self.connection_lost.emit()
                        return None
                    try_count += 1
                    continue

                data += chunk
                try_count = 0  # 重置重试计数器
            except socket.timeout:
                continue  # 超时后继续等待
            except BlockingIOError:
                continue  # 非阻塞模式兼容
            except Exception as e:
                print(f"接收错误 2: {str(e)}")
                self.update_message.emit("网络连接中断 2！")
                self.is_connected = False
                return None

        return data if len(data) == length else None

    # 连接服务器
    def connect_server(self):
        try:
            if self.client_socket:
                self.client_socket.close()
                self.client_socket = None
            self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.client_socket.settimeout(0.3)
            self.client_socket.connect((self.ip, PORT))
            self.is_connected = True
            self.update_message.emit("服务器连接成功！")
            # 启动接收线程
            self.receive_thread = threading.Thread(
                target=self.receive_loop,
                daemon=True,
                name="ReceiveThread"
            )
            self.receive_thread.start()
        except Exception as e:
            self.update_message.emit(f"服务器连接失败: {e}")
            self.is_connected = False

    # 处理响应协议
    def _handle_response(self, body):
        """统一处理响应协议"""
        try:
            rsp = RSP()
            rsp.ParseFromString(body)
            # print(f"rsp:{rsp}")
            if rsp.type == TRANS_TYPE_LOGIN:
                self.response_login(rsp)
            elif rsp.type == TRANS_TYPE_CHECK_SVR:
                self.response_check_svr(rsp)
            elif rsp.type == TRANS_TYPE_GET_SVR_DATA:
                self.response_get_svr_data(rsp)
            elif rsp.type == TRANS_TYPE_LOCK_SVR:
                self.response_lock(rsp)
            elif rsp.type == TRANS_TYPE_AUTOMAKE:
                self.response_automake(rsp)
            elif rsp.type == TRANS_TYPE_KILL_CFG:
                self.response_kill_cfg(rsp)
            elif rsp.type == TRANS_TYPE_RELOAD:
                self.response_reload(rsp)
            elif rsp.type == TRANS_TYPE_STOP:
                self.response_stop(rsp)
            elif rsp.type == TRANS_TYPE_DEL_SVR:
                self.response_del_svr(rsp)
            elif rsp.type == TRANS_TYPE_SYN:
                self.response_syn(rsp)
            elif rsp.type == TRANS_TYPE_DUMP:
                self.response_dump(rsp)
            elif rsp.type == TRANS_TYPE_SET_SVR_TIME:
                self.response_set_svr_time(rsp)
            elif rsp.type == TRANS_TYPE_ASK:
                self.response_ask(rsp)
            elif rsp.type == TRANS_TYPE_SVN_INFO:
                self.response_svninfo(rsp)
            elif rsp.type == TRANS_TYPE_ENTER:
                self.response_enter(rsp)
            elif rsp.type == TRANS_TYPE_CHANGE_SET_ID:
                self.response_change_set_id(rsp)
            elif rsp.type == TRANS_TYPE_CHANGE_GM_STATE:
                self.response_change_gm_state(rsp)
            else:
                self.update_message.emit(f"未知响应类型: {rsp.type}")

        except Exception as e:
            self.update_message.emit(f"响应解析失败: {str(e)}")

    # 处理通知协议
    def _handle_notification(self, body):
        """处理通知协议"""
        try:
            ntf = NTF()
            ntf.ParseFromString(body)
            print(f"收到通知: {ntf.svr_role_num} {ntf.update_time}")
            self.notification(ntf)
        except Exception as e:
            self.update_message.emit(f"通知解析失败: {str(e)}")

    def _handle_svn_info_notification(self, body):
        """处理通知协议"""
        try:
            ntf = SVN_INFO_NTF()
            ntf.ParseFromString(body)
            self.notification_svn_info(ntf)
        except Exception as e:
            self.update_message.emit(f"通知解析失败: {str(e)}")

    def _handle_server_list_notification(self, body):
        """处理动态服务器组数据"""
        try:
            ntf = SERVER_LIST_NTF()
            ntf.ParseFromString(body)

            # 动态更新全局服务器数据
            global server_list
            server_list = {
                group.group_name: list(group.server_ids)
                for group in ntf.server_groups
            }

            # 刷新UI显示
            self._setup_servers()
            self.change_page_list()
        except Exception as e:
            self.update_message.emit(f"服务器数据解析失败: {str(e)}")

    """----------------------发包处理------------------"""

    def check_cd(self):
        """检查冷却时间"""
        current_time = time.time()
        if current_time - self.last_send_time < 1:
            self.update_message.emit(f"操作过于频繁。")
            return False
        self.last_send_time = current_time
        return True

    def check_socket(self):
        if not self.client_socket:
            self.update_message.emit("未连接服务器！")
            return False
        return True

    def check_send_common(self):
        if self.check_socket() is False:
            return False
        if self.check_cd() is False:
            return False
        if self.c_lock_name != "":
            if self.c_lock_name != self.name:
                self.update_message.emit(f"服务器被[{self.c_lock_name}]锁定！")
                return False
        if self.c_run_state == 1:
            self.update_message.emit(f"服务器正在执行中！")
            return False
        return True

    """----------------------触发事件------------------"""
    """返回切页"""

    def return_page_enter(self):
        self.change_page(PAGE_ENTER)

    def change_page_list(self):
        self.change_page(PAGE_SERVER_LIST)

    def change_page_main(self):
        self.change_page(PAGE_SERVER_MAIN)

    def change_page_func(self):
        self.change_page(PAGE_SERVER_FUNC)

    def send_enter(self):
        if self.check_socket() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_ENTER,
                                           param_1=VERSION))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_change_set_id(self):
        if self.check_socket() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_CHANGE_SET_ID,
                                           param_1=VERSION))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_login(self):
        if self.check_socket() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_LOGIN,
                                           param_1=VERSION))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_check_svr(self):
        if self.check_socket() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_CHECK_SVR))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_get_svr_data(self):
        if self.check_socket() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_GET_SVR_DATA))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")

    def send_lock(self):
        if self.check_socket() is False:
            return
        try:
            param_1 = 0
            if self.pushButton_lock.text == "锁定":
                param_1 = 1
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_LOCK_SVR,
                                           param_1=param_1))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_automake(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_AUTOMAKE))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_kill_cfg(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_KILL_CFG))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_reload(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_RELOAD))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_stop(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_STOP))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_del_svr(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_DEL_SVR))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_syn(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_SYN,
                                           param_1=self.comboBox_2.currentIndex()
                                           ))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_ask(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_ASK))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    def send_svninfo(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_SVN_INFO))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()


    def send_dump(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_DUMP,
                                           param_1=int(self.lineEdit_txt_1.text()),
                                           param_2=int(self.lineEdit_txt_2.text()),
                                           param_3=int(self.lineEdit_txt_3.text())
                                           ))
            self.lineEdit_txt_3.clear()
        except Exception as e:
            self.show_dialog.emit("失败！请检查参数。")

    def send_set_svr_time(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_SET_SVR_TIME,
                                           param_1 = int(self.lineEdit_txt_4.text())
                                           ))
            self.lineEdit_txt_4.clear()
        except Exception as e:
            self.show_dialog.emit("失败！请检查参数。")

    def send_change_gm_state(self):
        if self.check_send_common() is False:
            return
        try:
            self.send_message(CMD_REQ, REQ(name=self.name,
                                           set_id=self.set_id,
                                           type=TRANS_TYPE_CHANGE_GM_STATE))
        except Exception as e:
            self.update_message.emit(f"发送失败: {str(e)}")
            self.return_page_enter()

    """----------------------回包处理------------------"""

    def response_login(self, rsp):
        if rsp.result != RET_SUCCESS:
            if rsp.result == RET_FAIL_10004:
                self.exit_dialog.emit(f"版本号不匹配！请更新最新版本")
            else:
                self.update_message.emit("登陆失败！")

    def response_check_svr(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.label_deng.setStyleSheet("border-radius:10px;background-color:rgb(0, 234, 0)")
        else:
            self.label_deng.setStyleSheet("border-radius:10px;background-color:red")

    def result_error(self, rsp):
        if rsp.result == RET_FAIL_10001:
            self.update_message.emit("服务器当前区服数据不存在！")
        elif rsp.result == RET_FAIL_10002:
            self.update_message.emit("主干服务器正在执行中, 稍等片刻后再试！")
        elif rsp.result == RET_FAIL_10003:
            self.update_message.emit("不是主干服，别闹！")
        elif rsp.result == RET_FAIL_10004:
            self.update_message.emit("版本不一致，请更新最新版本！")
        else:
            self.update_message.emit(f"操作失败! {rsp.result}")

    def response_get_svr_data(self, rsp):
        if rsp.result == RET_SUCCESS:
            pass
        else:
            self.result_error(rsp)

    def response_lock(self, rsp):
        if rsp.result == RET_SUCCESS:
            pass
        else:
            self.result_error(rsp)

    def response_automake(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("出包执行成功！")
        else:
            self.result_error(rsp)

    def response_kill_cfg(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("热更配置执行成功！")
        else:
            self.result_error(rsp)

    def response_reload(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("启服执行成功！")
        else:
            self.result_error(rsp)

    def response_stop(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("停服执行成功！")
        else:
            self.result_error(rsp)

    def response_del_svr(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("删档执行成功！")
        else:
            self.result_error(rsp)

    def response_syn(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("同步执行成功！")
        else:
            self.result_error(rsp)

    def response_dump(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.show_dialog.emit("导号执行成功！")
        else:
            self.update_message.emit(f"导号操作失败! {rsp.result}")

    def response_set_svr_time(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.show_dialog.emit("开服时间执行成功！")
        else:
            self.update_message.emit(f"开服时间操作失败! {rsp.result}")

    def response_ask(self, rsp):
        if rsp.result == RET_SUCCESS:
            msg = f"用户[{rsp.name}]询问可否操作服务器？"
            self.show_dialog.emit(msg)
        else:
            pass

    def response_svninfo(self, rsp):
        if rsp.result == RET_SUCCESS:
            pass
        else:
            self.result_error(rsp)

    def response_enter(self, rsp):
        pass

    def response_change_set_id(self, rsp):
        pass

    def response_change_gm_state(self, rsp):
        if rsp.result == RET_SUCCESS:
            self.send_check_svr()
            self.show_dialog.emit("GM切换成功！")
        else:
            self.result_error(rsp)


    """----------------------广播处理------------------"""

    def notification(self, ntf):
        if ntf.set_id != self.set_id:
            return
        # 锁的处理
        if ntf.lock_name == "":
            self.pushButton_lock.text = '锁定'
            self.pushButton_lock.setIcon(QIcon(":client/images/lock_a.jpg"))
        else:
            self.update_message.emit(f"用户[{ntf.lock_name}]锁定服务器！")
            self.pushButton_lock.text = "解锁"
            self.pushButton_lock.setIcon(QIcon(":client/images/lock_b.jpg"))

        # 运行状态的处理
        if ntf.run_state == 0:
            self.stop_progress_bar()
            if self.c_run_state != ntf.run_state:
                self.update_message.emit(f"用户[{self.c_cur_name}]的[{self.c_task_name}]任务执行完成！")
        else:
            if self.c_run_state != ntf.run_state:
                self.update_message.emit(f"用户[{ntf.cur_name}]的[{ntf.task_name}]任务正在执行！")
            self.start_progress_bar()
        self.c_lock_name = ntf.lock_name
        self.c_run_state = ntf.run_state
        self.c_cur_name = ntf.cur_name
        self.c_task_name = ntf.task_name
        self.label_svr_role_num.setText(str(ntf.svr_role_num))

        # 处理时间戳
        def format_timestamp(ts):
            if ts == 0:
                return "未更新"  # 或返回空字符串 ""
            try:
                # 假设时间戳是毫秒级（如 1633046400000）
                ts_seconds = ts / 1000 if ts > 1e12 else ts  # 自动判断是否需要转换
                return datetime.fromtimestamp(ts_seconds).strftime("%Y-%m-%d %H:%M:%S")
            except (TypeError, ValueError, OSError):
                return "时间无效"

        temp_update_time = format_timestamp(ntf.update_time)
        print(f"update_time: {temp_update_time}")

        self.label_update_time.setText(temp_update_time)

    def notification_svn_info(self, ntf):
        self.update_message.emit(f"\n配置目录：{ntf.config_svn_url}"
                                 f"\n代码目录：{ntf.src_svn_url}")

# 添加主程序入口
if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = Client()  # 创建窗口实例
    window.show()  # 显示窗口
    sys.exit(app.exec_())  # 进入主事件循环
